package com.amoby.base.utils.ftp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

public class SFTPClient {
    private static final Logger logger = LoggerFactory.getLogger(SFTPClient.class);
    private String              site;
    private String              loginId;
    private String              sshKeyPath;
    private JSch                jsch   = new JSch();                               // 创建JSch对象
    private Session             session;
    private ChannelSftp         sftp;

    // public static void main(String[] args) throws JSchException, SftpException {
    // SFTPClient client = new SFTPClient("192.168.10.32", "root", "C:/Users/Administrator/Desktop/id_rsa_2048");
    //
    // client.connect();
    //
    // @SuppressWarnings("unchecked")
    // List<LsEntry> list = client.sftp.ls("/root");
    // for (LsEntry e : list) {
    // System.out.println(e);
    // }
    //
    // client.disconnect();
    // }
    public SFTPClient(String site, String loginId, String sshKeyPath) throws JSchException {
        this.site = site;
        this.loginId = loginId;
        this.sshKeyPath = sshKeyPath;
        jsch.addIdentity(this.sshKeyPath);
    }

    @SuppressWarnings("unchecked")
    public synchronized List<LsEntry> ls(String path) throws SftpException {
        if (sftp == null) {
            throw new IllegalStateException("not connection");
        }
        return sftp.ls(path);
    }

    public synchronized void put(InputStream src, String dst) throws SftpException {
        if (sftp == null) {
            throw new IllegalStateException("not connection");
        }
        sftp.put(src, dst, ChannelSftp.OVERWRITE);
    }

    public synchronized void put(File file, String dst) throws SftpException, IOException {
        InputStream src = null;
        try {
            src = new BufferedInputStream(new FileInputStream(file));
            put(src, dst);
        } catch (Exception e) {
            throw e;
        } finally {
            if (src != null) {
                src.close();
                src = null;
            }
        }
    }

    public synchronized void get(String src, OutputStream dst) throws SftpException {
        if (sftp == null) {
            throw new IllegalStateException("not connection");
        }
        sftp.get(src, dst);
    }

    public synchronized void get(String src, File file) throws SftpException, IOException {
        OutputStream dst = null;
        try {
            dst = new BufferedOutputStream(new FileOutputStream(file));
            get(src, dst);
        } catch (Exception e) {
            throw e;
        } finally {
            if (dst != null) {
                dst.flush();
                dst.close();
                dst = null;
            }
        }
    }

    public synchronized void rm(String path) throws SftpException {
        if (sftp == null) {
            throw new IllegalStateException("not connection");
        }
        sftp.rm(path);
    }

    public synchronized boolean isConnected() {
        if (sftp == null) return false;
        return sftp.isConnected();
    }

    public synchronized void connect() throws JSchException {
        session = jsch.getSession(loginId, site); // 根据用户名，主机ip，端口获取一个Session对象
        logger.trace("SFTP Session created.");
        // 忽略公钥验证
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        // session.setTimeout(timeout);
        session.connect();
        logger.trace("SFTP Session connected.");
        logger.trace("SFTP Opening Channel.");
        sftp = (ChannelSftp) session.openChannel("sftp"); // 打开SFTP通道
        sftp.connect(); // 建立SFTP通道的连接
        logger.info("SFTP Connected successfully to ftpHost = " + site + ",as ftpUserName = " + loginId + ", returning: " + sftp);
    }

    public synchronized void disconnect() {
        String host = null;
        if (sftp != null) {
            sftp.disconnect();
            sftp = null;
        }
        if (session != null) {
            host = session.getHost();
            session.disconnect();
            session = null;
        }
        logger.info("SFTP Session disconnected. host = " + host);
    }
}
